package com.xgkj.diyiketang.util;

import java.io.StringReader;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.xmlpull.v1.XmlPullParser;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.util.Xml;

import com.tencent.mm.sdk.modelpay.PayReq;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.xgkj.diyiketang.EatShowApp;
import com.xgkj.diyiketang.ProtocolConst;
import com.xgkj.diyiketang.R;
import com.xgkj.diyiketang.security.MD5;
import com.xgkj.diyiketang.security.WeixinMD5;

public class WeiXinPay {
	private static final String TAG = "WeixinPay";
	PayReq req;
	IWXAPI msgApi = null;
	Map<String, String> resultunifiedorder;
	private Activity mActivity ;
	private String mOrderNo;
	private String mOrderTitle;
	private String mOrderBody;
	private String mOrderPrice;
	
	

	public WeiXinPay(IWXAPI api,Activity activity,String orderNo,String orderBody, String orderPrice) {
		msgApi = api;
		req = new PayReq();
		mActivity = activity;
		mOrderNo = orderNo;
//		mOrderTitle = orderTitle;
		mOrderBody = orderBody;
		double money = 0;
		try {
			money = Double.parseDouble(orderPrice);
		} catch (Exception e) {
			e.printStackTrace();
		}
		mOrderPrice = String.valueOf((int)(money * 100));
		GetPrepayIdTask getPrepayId = new GetPrepayIdTask();
		getPrepayId.execute();
	}
	

	public class GetPrepayIdTask extends AsyncTask<Void, Void, Map<String, String>> {

		private ProgressDialog dialog;

		@Override
		protected void onPreExecute() {
			dialog = ProgressDialog.show(mActivity, "", mActivity.getString(R.string.get_pageinfo_loading));
		}

		@Override
		protected void onPostExecute(Map<String, String> result) {
			if (dialog != null) {
				dialog.dismiss();
			}

			resultunifiedorder = result;
			genPayReq();

		}

		@Override
		protected void onCancelled() {
			super.onCancelled();
		}

		@Override
		protected Map<String, String> doInBackground(Void... params) {

			String url = String
					.format("https://api.mch.weixin.qq.com/pay/unifiedorder");
			String entity = genProductArgs();
			PalLog.e(TAG, entity);

			byte[] buf = WeiXinPayUtil.httpPost(url, entity);

			String content = new String(buf);
			Map<String, String> xml = decodeXml(content);

			return xml;
		}
	}

	public Map<String, String> decodeXml(String content) {

		try {
			Map<String, String> xml = new HashMap<String, String>();
			XmlPullParser parser = Xml.newPullParser();
			parser.setInput(new StringReader(content));
			int event = parser.getEventType();
			while (event != XmlPullParser.END_DOCUMENT) {

				String nodeName = parser.getName();
				switch (event) {
				case XmlPullParser.START_DOCUMENT:

					break;
				case XmlPullParser.START_TAG:

					if ("xml".equals(nodeName) == false) {
						// 实例化student对象
						xml.put(nodeName, parser.nextText());
					}
					break;
				case XmlPullParser.END_TAG:
					break;
				}
				event = parser.next();
			}

			return xml;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;

	}

	private String genNonceStr() {
		Random random = new Random();
		return MD5.digest(String.valueOf(random.nextInt(10000)));
	}

	private long genTimeStamp() {
		return System.currentTimeMillis() / 1000;
	}

//	private String genOutTradNo() {
//		Random random = new Random();
//		return MD5.digest(String.valueOf(random.nextInt(10000)));
//	}

	//
	private String genProductArgs() {
//		StringBuffer xml = new StringBuffer();

		try {
			String nonceStr = genNonceStr();

//			xml.append("</xml>");
			List<NameValuePair> packageParams = new LinkedList<NameValuePair>();
			packageParams.add(new BasicNameValuePair("appid",
					ProtocolConst.APP_ID));
			packageParams.add(new BasicNameValuePair("body", mOrderBody));
			packageParams.add(new BasicNameValuePair("mch_id",
					ProtocolConst.MCH_ID));
			packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));
			packageParams.add(new BasicNameValuePair("notify_url",
					ProtocolConst.WEIXIN_NOTIFY_URL));
			packageParams.add(new BasicNameValuePair("out_trade_no",
					mOrderNo));
			packageParams.add(new BasicNameValuePair("spbill_create_ip",
					"127.0.0.1"));
			packageParams.add(new BasicNameValuePair("total_fee", mOrderPrice));
			packageParams.add(new BasicNameValuePair("trade_type", "APP"));

			String sign = genPackageSign(packageParams);
			packageParams.add(new BasicNameValuePair("sign", sign));

			String xmlstring = toXml(packageParams);

			return new String(xmlstring.getBytes(),"ISO8859-1");

		} catch (Exception e) {
			PalLog.e(TAG , "genProductArgs fail, ex = " + e.getMessage());
			return null;
		}

	}

	private void genPayReq() {

		req.appId = ProtocolConst.APP_ID;
		req.partnerId = ProtocolConst.MCH_ID;
		req.prepayId = resultunifiedorder.get("prepay_id");
		req.packageValue = "Sign=WXPay";
		req.nonceStr = genNonceStr();
		req.timeStamp = String.valueOf(genTimeStamp());

		List<NameValuePair> signParams = new LinkedList<NameValuePair>();
		signParams.add(new BasicNameValuePair("appid", req.appId));
		signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));
		signParams.add(new BasicNameValuePair("package", req.packageValue));
		signParams.add(new BasicNameValuePair("partnerid", req.partnerId));
		signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
		signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));

		req.sign = genAppSign(signParams);

		sendPayReq();

	}

	private void sendPayReq() {

		msgApi.registerApp(ProtocolConst.APP_ID);
		msgApi.sendReq(req);

		EatShowApp.getACache().put("pay_success","true");
	}

	private String genPackageSign(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < params.size(); i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(ProtocolConst.API_KEY);

		String packageSign = WeixinMD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
		return packageSign;
	}

	private String genAppSign(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < params.size(); i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(ProtocolConst.API_KEY);

		// this.sb.append("sign str\n" + sb.toString() + "\n\n");
		String appSign = WeixinMD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
		return appSign;
	}

	private String toXml(List<NameValuePair> params) {
		StringBuilder sb = new StringBuilder();
		sb.append("<xml>");
		for (int i = 0; i < params.size(); i++) {
			sb.append("<" + params.get(i).getName() + ">");

			sb.append(params.get(i).getValue());
			sb.append("</" + params.get(i).getName() + ">");
		}
		sb.append("</xml>");

		return sb.toString();
	}

}
